-- Pet
-- Create by weism
-- 宠物对象

Pet = {
    classId = 0,
    hp     = 0,
    mp     = 0,
    level  = 0,
    rank   = 0,
    skill  = 0,
    attr   = 0,
    style  = 0,
    special = 0,
    modelId = 0,
    skills  = {},
    skillOption = {},
    equipments = {},
    upgradeProp = {},
    feedRecord = {};

    -- 对象类型为宠物
    type = OBJECT_TYPE_PET,
};
Pet.__index = Pet;

-- 构造函数
function Pet.new(classId, data, empty)
    local self = {};
    setmetatable(self, Pet);
    self.classId = classId;
    self.bonus = bonus;
    self.dbase = Dbase.new(data);

    -- 设置宠物的数据
    if data.rank ~= nil then self.rank = data.rank end
    if data.level ~= nil then self.level = data.level end
    if data.soul ~= nil then self.soul = data.soul end
    if data.special ~= nil then self.special = data.special end
    self.modelId = self:query("default_model");

    -- 如果不需要数据
    if empty then
        return self;
    end

    -- 初始化职业系别数据
    self:updateCareerData(CareerM.restoreCareerData(data.career or {}), false);

    if data.equipments ~= nil then
        local equip = {};
        for k, v in pairs(data.equipments) do
            equip[k] = v;
        end
        self.equipments = equip;
    else
        self.equipments = {};
    end

    if self.equipments[EQUIP_TYPE_COSTUME] then
        local equipedCostumeId = self.equipments[EQUIP_TYPE_COSTUME][1] or 0;
        if equipedCostumeId > 0 then
            self.modelId = EquipM.queryPetModelID(equipedCostumeId) or self.modelId;
        end
    end

    if data.upgrade_prop ~= nil then
        self.upgradeProp = data.upgrade_prop;
    end

    if data.feed_record ~= nil then
        self.feedRecord = data.feed_record;
    else
        self.feedRecord = {};
    end

    self.style = self:query("style")
    self.attr = self:query("type")

    self.hp = self:getMaxHp();
    self.mp = self:getMp();
    return self;
end

-- 取得该对象的描述字符串
function Pet:get_ob_id()
    return string.format("Pet:%s", tostring(self.classId));
end

-- 查找数据
function Pet:query(path)
    if path == "classId"    then return self.classId;
    elseif path == "level"  then return self.level;
    else
        return PetM.query(self.classId, path);
    end
end

-- 获取模型ID
function Pet:getModelId()
    if ServerStatusM.query(MODULE_SWITCH_OPEN_COSTUME) ~= 1 then
        -- 屏蔽时装功能，返回默认时装ID
        return self:query("default_model");
    end

    return self.modelId;
end

-- 设置模型ID
function Pet:setModelId(modelId)
    self.modelId = modelId;
end

-- 获取小图标
function Pet:getIcon()
    if ServerStatusM.query(MODULE_SWITCH_OPEN_COSTUME) ~= 1 then
        -- 屏蔽时装功能，默认时装
        return PetM.getDefaultIcon(self:getModelId());
    end

    local modelId = self.modelId;
    return PetM.queryModel(modelId, "icon");
end

-- 获取图标
function Pet:getLargeIcon()
    if ServerStatusM.query(MODULE_SWITCH_OPEN_COSTUME) ~= 1 then
        -- 屏蔽时装功能，默认时装
        return PetM.getDefaultLargeIcon(self:getModelId());
    end

    local modelId = self.modelId;
    return PetM.queryModel(modelId, "large_icon");
end

-- 宠物后天技能
function Pet:getSkills()
    -- 所有后天学习的技能
    return self.skills;
end

-- 宠物所有技能
function Pet:getAllSkills(onlyCareer)
    local skills = CareerM.getCareerSkills(self);

    if self.special > 0 and onlyCareer ~= true then
        table.insert(skills, 1, self.special);
    end

    return skills;
end

-- 宠物专属技能
function Pet:getSpecial()
    if nil == self.special or 0 == self.special then
        return PetM.query(self.classId, "special");
    end

    return self.special;
end

-- 获取升阶增加的攻击力
function Pet:getUpRankAddAttack(rank)
    if not rank then
        rank = self.rank;
    end

    return PetM.getPetUpRankAddAttrib(self.classId, rank, "attack");
end

-- 获取升阶增加的魔力
function Pet:getUpRankAddMagic(rank)
    if not rank then
        rank = self.rank;
    end

    return PetM.getPetUpRankAddAttrib(self.classId, rank, "magic");
end

-- 获取升阶增加的最大生命值
function Pet:getUpRankAddMaxHp(rank)
    if not rank then
        rank = self.rank;
    end

    return PetM.getPetUpRankAddAttrib(self.classId, rank, "max_hp");
end

-- 获取升阶增加的最大魔法值
function Pet:getUpRankAddMaxMp(rank)
    if not rank then
        rank = self.rank;
    end

    return PetM.getPetUpRankAddAttrib(self.classId, rank, "max_mp");
end

-- 获取升阶增加的可喂食次数
function Pet:getUpRankAddFeedTimes(rank)
    if not rank then
        rank = self.rank;
    end

    local nextRankFeedTimes = PetM.maxLevelByRank(self, rank);
    return nextRankFeedTimes - PetM.maxLevelByRank(self, rank - 1);
end

-- 获取升阶开启的称号系别
function Pet:getUpRankAddCareerType(rank)
    if not rank then
        rank = self.rank;
    end

    local nextRankCareerType = CareerM.getDepartmentList(self, rank);
    local curRankCareerType = CareerM.getDepartmentList(self, rank - 1);

    if #nextRankCareerType > #curRankCareerType then
        return nextRankCareerType[#nextRankCareerType];
    else
        return 0;
    end
end


-- 查询属性
function Pet:queryAttrib(attrib, args)
    return AttribM.queryAttrib(self, attrib, args);
end

-- 计算最大血量
function Pet:getMaxHp()
    local maxHp = self:query("hp");

    -- 1. 加成
    local prop = PropM.combine(self, "attrib2", "max_hp");
    maxHp = PropM.apply(prop, maxHp);

    -- 2. 加成
    prop = PropM.combine(self, "attrib", "max_hp");
    maxHp = PropM.apply(prop, maxHp);

    return maxHp;
end

-- 当前血量
function Pet:getHp()
    return self:getMaxHp();
end

-- 获取魔法值
function Pet:getMp()
    return self:getMaxMp();
end

-- 获取最大魔法值
function Pet:getMaxMp()
    local maxMp = self:query("mp");

    -- 1. 加成
    local prop = PropM.combine(self, "attrib2", "max_mp");
    maxMp = PropM.apply(prop, maxMp);

    -- 2. 加成
    prop = PropM.combine(self, "attrib", "max_mp");
    maxMp = PropM.apply(prop, maxMp);

    return maxMp;
end

-- 计算基础攻击值
function Pet:getAttack()
    local attack = self:query("attack");

    -- 1. 加成
    local prop = PropM.combine(self, "attrib", "attack");
    attack = PropM.apply(prop, attack);

    -- 2. 加成
    prop = PropM.combine(self, "attrib2", "attack");
    attack = PropM.apply(prop, attack);

    return attack;
end

-- 计算基础魔法值
function Pet:getMagic()
    local magic = self:query("magic");

    -- 1. 加成
    local prop = PropM.combine(self, "attrib", "magic");
    magic = PropM.apply(prop, magic);

    -- 2. 加成
    prop = PropM.combine(self, "attrib2", "magic");
    magic = PropM.apply(prop, magic);

    return magic;
end

-- 获取阶位
function Pet:getRank()
    return self.rank or 0;
end

-- 设置阶位
function Pet:setRank(rank)
    -- 阶位必须合法
    assert(rank > 0 and rank <= self:query("max_rank"));

    self.rank = rank;
end

-- 获取等级(目前没有等级的概念，用喂食次数替代)
function Pet:getLevel()
    return #self:getFeedRecord() + 1;
end

-- 设置等级
function Pet:setLevel(level)
    self.level = level;
end

-- 设置当前装备的武器/徽章
function Pet:setEquipments(equips)
    self.equipments = equips;
end

-- 设置技能
function Pet:setSkills(skills)
    self.skills = skills;
end

-- 设置喂食记录
function Pet:setFeedRecord(feedRecord)
    self.feedRecord = feedRecord;
end

-- 喂食记录
function Pet:getFeedRecord()
    return self.feedRecord or {};
end

-- 获取升级属性信息
function Pet:getUpgradeProp()
    return self.upgradeProp;
end

-- 设置升级属性信息
function Pet:setUpgradeProp(upgradeProp)
    self.upgradeProp = upgradeProp;
end

-- 获取属性提升值
function Pet:getUpgradePropValue(type)
    local add = 0;
    type = tostring(type);
    if self.upgradeProp[type] ~= nil and self.upgradeProp[type]["add_value"] ~= nil then
        add = self.upgradeProp[type]["add_value"];
    end

    return add;
end

-- 获取属性提升次数
function Pet:getUpgradePropTimes(type)
    local times = 0;
    type = tostring(type);
    if self.upgradeProp[type] ~= nil and self.upgradeProp[type]["add_times"] ~= nil then
        times = self.upgradeProp[type]["add_times"];
    end

    return times;
end

-- 获取系别职业信息
function Pet:getCareerData(departmentId)
    local careerData = self.career or {};

    if departmentId then
        return careerData[departmentId] or {};
    end

    return careerData;
end

-- 更新系别职业信息
function Pet:updateCareerData(careerData, refresh)
    if nil == refresh then refresh = true end
    self.career = careerData;

    -- 刷新下玩家的属性
    if refresh and ME.isInGame then
        PropM.refreshEffect(ME.user, "skill");
        PropM.refreshEffect(ME.user, "equip");
    end
end

-- 获取保存数据
function Pet:getSaveData()
    return {
        ["rank"] = self:getRank(),
        ["level"] = self:getLevel(),
        ["special"] = self:getSpecial(),
        ["equipments"] = self.equipments,
        ["upgradeProp"] = self:getUpgradeProp(),
        ["career"] = CareerM.packCareerData(table.deepcopy(self:getCareerData())),
        ["feedRecord"] = self:getFeedRecord(),
    };
end

-- 还原数据
function Pet:restoreData(data)
    self:setRank(data.rank);
    self:setLevel(data.level);
    self.special = data.special;
    self.equipments = data.equipments;
    self:setUpgradeProp(data.upgradeProp);
    self:updateCareerData(data.career);
    self:setFeedRecord(data.feedRecord);
end

-- 获取宠物的天赋技能id
function Pet:getTalentSkillId()
    local level    = self:getRank();
    if AwakeM.isCarved(self.classId) then
        level = level + 1;
    end

    local skillId = self:query("talent");
    skillId = TalentM.getTalentByRank(skillId, level);

    return skillId;
end